#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
struct msg {
  struct msg *m_next;
  /* ... more stuff here ... */
  char *c;
};

struct msg *workq;

pthread_cond_t qready = PTHREAD_COND_INITIALIZER;

pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;

void *process_msg(void *in) {
  struct msg *mp;

  for (;;) {
    pthread_mutex_lock(&qlock);
    while (workq == NULL)
      pthread_cond_wait(&qready, &qlock);
    mp = workq;
    workq = mp->m_next;

    printf("------> thread id = %d get msg %s\n", (unsigned int)pthread_self(),
           mp->c);
    free(mp);
    pthread_mutex_unlock(&qlock);
    /* now process the message mp */
  }

  int *result = malloc(sizeof(int));
  *result = 0;
  return result;
}

void enqueue_msg(struct msg *mp) {
  pthread_mutex_lock(&qlock);
  mp->m_next = workq;
  workq = mp;
  pthread_mutex_unlock(&qlock);
  pthread_cond_signal(&qready);
}
